package org.zoomdev.zoom.hash;

import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

public class ConsistentHash {
    private final TreeMap<Integer, String> ring = new TreeMap<>();
    private final int virtualNodesPerShard;

    public ConsistentHash(List<String> nodes, int virtualNodesPerShard) {
        this.virtualNodesPerShard = virtualNodesPerShard;
        for (String node : nodes) {
            addNode(node);
        }
    }

    public String getNode(String key) {
        int hash = hashFunction(key);
        SortedMap<Integer, String> tailMap = ring.tailMap(hash);
        int nodeHash = tailMap.isEmpty() ? ring.firstKey() : tailMap.firstKey();
        return ring.get(nodeHash);
    }

    private void addNode(String node) {
        for (int i = 0; i < virtualNodesPerShard; i++) {
            String vNode = node + "#VN" + i;
            int hash = hashFunction(vNode);
            ring.put(hash, node);
        }
    }

    private int hashFunction(String key) {
        final int FNV_32_INIT = 0x811c9dc5;
        final int FNV_32_PRIME = 0x01000193;
        int hash = FNV_32_INIT;
        for (byte b : key.getBytes()) {
            hash ^= b;
            hash *= FNV_32_PRIME;
        }
        return hash & 0x7fffffff; // 确保非负数

        //return Hashing.murmur3_32().hashUnencodedChars(key).asInt() & 0x7FFFFFFF;
    }

}